<template lang="html">
  <div>
    <input type="file" accept=".docx,.pdf" ref="fileInput" @change="uploadFile($event.target)" style="display: none">
    <div ref="wangeditor" class="text"></div>
    <el-drawer
      :append-to-body="true"
      :wrapperClosable="false"
      title="插入公式"
      size="840px"
      :visible.sync="open"
      @close="handleClose"
    >
      <div class="drawer_container">
        <div class="drawer_content">
          <iframe ref="inputIFrameRef" class="iframe" height="560px" width="100%" frameborder="0" src="/kityformula/FormulaDrawer.html"></iframe>
        </div>
        <div class="bottom_btns">
          <el-button @click="handleClose">取消</el-button>
          <el-button type="primary" @click="sureBtn">确定</el-button>
        </div>
      </div>
    </el-drawer>
  </div>

</template>

<script>
import E from "wangeditor";
const pdfjsLib = window["pdfjs-dist/build/pdf"];
import { uploadOSS, fammterString } from "@/api/upload";
import { base64ToFile } from "@/utils/base64ToFile";
import axios from "axios";
const { BtnMenu } = E;

export default {
  data() {
    return {
      wangEditor: null,
      wangEditorInfo: null,
      fullscreen: false,
      open:false,
    };
  },
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    uuid: {
      type: [String, Number],
      default: "",
    },
    isgetIndex: {
      type: [String, Number],
      default: "0",
    },
    courseId: {
      type: [String, Number],
      default: "",
    },
    placeholder: {
      type: String,
      default: "请输入正文",
    },
    value: {
      type: String,
      default: "",
    },
    isClear: {
      type: Boolean,
      default: false,
    },
    stepIndex: Number,
    importOpen: {
      type: Boolean,
      default: true,
    },
  },
  watch: {
    placeholder(e) {
      console.log(e);
    },
    isClear(val) {
      // 触发清除文本域内容
      if (val) {
        this.wangEditor.txt.clear();
        this.wangEditorInfo = null;
      }
    },
    value: function (value) {
      if (value !== this.wangEditor.txt.html()) {
        this.isClear = false;
        this.wangEditor.txt.html(this.value); //value为编辑框输入的内容，这里我监听了一下值，当父组件调用得时候，如果给value赋值了，子组件将会显示父组件赋给的值
      }
    },
  },
  mounted() {
    this.initEditor();
    this.wangEditor.txt.html(this.value);
    document
      .querySelector(".w-e-icon-fullscreen")
      .addEventListener("click", () => {
        this.fullscreen = true;
        let text = document.querySelector(".w-e-text");
        text.classList.add("fullscreen_text");
      });
    if (document.querySelector(".w-e-icon-fullscreen_exit")) {
      document
        .querySelector(".w-e-icon-fullscreen_exit")
        .addEventListener("click", () => {
          this.fullscreen = false;
          let text = document.querySelector(".w-e-text");
          text.classList.remove("fullscreen_text");
        });
    }
  },
  methods: {
    initEditor() {
      let that = this;

      class upLoadWord extends BtnMenu {
        constructor(editor) {
          const $elem = E.$(
            `<div class="w-e-menu" data-title="word导入">
                <img class="word_fs" src="" alt="加载失败">
            </div>`
          );
          super($elem, editor);
        }
        // 菜单点击事件
        clickHandler() {
          // 触发自定义事件，传递参数
          that.upLoadWord();
        }
        tryChangeActive() {
          this.active();
        }
      }

      class initFormula extends BtnMenu {
        constructor(editor) {
          const $elem = E.$(
            `<div class="w-e-menu" data-title="公式插入">
                  <svg t="1736298820386" class="word_fs" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4299" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 928H128a32 32 0 0 1-26.88-49.92L345.6 512 101.12 145.92A32 32 0 0 1 128 96h384a32 32 0 0 1 0 64H187.52l223.36 334.08a33.28 33.28 0 0 1 0 35.84L187.52 864H512a32 32 0 0 1 0 64zM640 928a36.48 36.48 0 0 1-17.92-5.12 32.64 32.64 0 0 1-8.96-44.8l256-384a32 32 0 0 1 53.76 35.84l-256 384a33.28 33.28 0 0 1-26.88 14.08z" fill="#595959" p-id="4300"></path><path d="M896 928a33.28 33.28 0 0 1-26.88-14.08l-256-384a32 32 0 1 1 53.76-35.84l256 384a32.64 32.64 0 0 1-8.96 44.8 36.48 36.48 0 0 1-17.92 5.12zM992 224h-320a32 32 0 0 1 0-64h320a32 32 0 0 1 0 64z" fill="#595959" p-id="4301"></path><path d="M832 384a32 32 0 0 1-32-32v-320a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32z" fill="#595959" p-id="4302"></path></svg>
                </div>`
          );
          super($elem, editor);
        }
        // 菜单点击事件
        clickHandler() {
          // 触发自定义事件，传递参数
          that.showFormula();
        }
        tryChangeActive() {
          this.active();
        }
      }

      this.wangEditor = new E(this.$refs.wangeditor);
      this.wangEditor.customConfig = this.wangEditor.customConfig
        ? this.wangEditor.customConfig
        : this.wangEditor.config;
      this.wangEditor.config.placeholder = this.placeholder;
      this.wangEditor.customConfig.uploadImgShowBase64 = true; // base64存储图片（推荐）
      // this.wangEditor.customConfig.uploadImgServer = "https://www.metaxun.com/mixedState/common/uploadInCourse"; // 配置服务器端地址（不推荐）
      this.wangEditor.customConfig.uploadImgHeaders = {}; // 自定义header
      this.wangEditor.customConfig.uploadFileName = "file"; // 后端接受上传文件的参数名
      this.wangEditor.customConfig.uploadImgMaxSize = 5 * 1024 * 1024; // 将图片大小限制为（默认最大支持2M）
      this.wangEditor.customConfig.uploadImgMaxLength = 1; // 限制一次最多上传6张图片
      this.wangEditor.customConfig.uploadImgTimeout = 1 * 60 * 1000; // 设置超时时间（默认1分钟）
      this.wangEditor.config.onblur = (newHtml) => {
        this.$emit("onblur", this.stepIndex);
      };
      //设置视频支持的类型
      this.wangEditor.config.uploadVideoAccept = ["mp4", "webm"];
      //隐藏插入网络视频的功能
      this.wangEditor.config.showLinkVideo = false;
      //隐藏插入网络图片的功能
      this.wangEditor.config.showLinkImg = false;
      // 配置菜单
      this.wangEditor.customConfig.menus = [
        "image", // 插入图片
        "video", // 插入视频
        this.importOpen ? "upLoadWord" : "", // word导入
        "head", // 标题
        "bold", // 粗体
        "fontSize", // 字号
        "fontName", // 字体
        "italic", // 斜体
        "underline", // 下划线
        "strikeThrough", // 删除线
        "foreColor", // 文字颜色
        "backColor", // 背景颜色
        "link", // 插入链接
        "list", // 列表
        "justify", // 对齐方式
        "quote", // 引用
        "emoticon", // 表情
        "table", // 表格
        this.importOpen ? "code" : "", // 插入代码
        "undo", // 撤销
        "redo", // 重复
        this.importOpen ? "fullscreen" : "", // 全屏
      ];
      if (this.isgetIndex == "1") {
        this.wangEditor.customConfig.menus = [
          "image", // 插入图片
          "head", // 标题
          "bold", // 粗体
          "fontSize", // 字号
          "fontName", // 字体
          "italic", // 斜体
          "underline", // 下划线
          "backColor", // 背景颜色
          "link", // 插入链接
          "list", // 列表
          "justify", // 对齐方式
          "quote", // 引用
          "emoticon", // 表情
          "code", // 插入代码
          "undo", // 撤销
          "redo", // 重复
          "fullscreen", // 全屏
        ];
      }

      this.wangEditor.menus.extend("upLoadWord", upLoadWord); // 配置扩展的菜单

      this.wangEditor.customConfig.customUploadImg = (files, insert) => {
        let file = new File(files, files[0].name, {
          type: files[0].type,
          lastModified: Date.now(),
        });
        let path = fammterString(2, this.uuid);
        uploadOSS(file, path).then((res) => {
          insert(res[0]); //将图片展示到编辑器中
        });
      };
      this.wangEditor.customConfig.customUploadVideo = (files, insert) => {
        let file = files[0];
        const formData = new FormData();
        if (file.size / 1024 / 1024 > 500) {
          this.$modal.msg("视频大小不能超过500MB");
          return false;
        }
        let path = fammterString(2, this.uuid);
        uploadOSS(file, path).then((res) => {
          insert(res[0]); //将图片展示到编辑器中
        });
      };
      this.wangEditor.customConfig.onchange = (html) => {
        if (this.isgetIndex == 1 && html == "") {
          this.wangEditor.txt.html(" &nbsp");
        }
        let str = html.replace(
          /<video src/g,
          '<video controlsList="nodownload" src'
        );
        str = str.replace(/<\/video><\/p>/g, "</video><br></p>");
        //关闭video标签的下载按钮
        this.wangEditorInfo = str;
        this.$emit("change", this.wangEditorInfo); // 将内容同步到父组件中
      };
      this.wangEditor.create();
    },
    upLoadWord() {
      const fileInput = this.$refs.fileInput;
      fileInput.click();
    },
    async uploadFile(event) {
      const file = this.$refs.fileInput.files[0];
      const formData = new FormData();
      formData.append("file", file); // 假设你有一个名为file的文件对象

      const loading = this.$loading({
        lock: true,
        text: `上传处理中,请稍等…(0%)`,
        spinner: "el-icon-loading",
        background: "rgba(255, 255, 255, 0.3)",
      });
      if (file.type == "application/pdf") {
        const pdfData = await this.readFileAsArrayBuffer(file);
        const pdfUrl = URL.createObjectURL(
          new Blob([pdfData], { type: "application/pdf" })
        );
        let str = await this.insertPdfAsImage(pdfUrl);
        loading.setText(`上传处理中,请稍等…(100%)`);
        loading.close();
        this.$emit("turnWord", str);
        console.log(str, "str");
      } else {
        axios
          .post("https://hgcc.metaxun.com/node/upload", formData, {
            onUploadProgress(e) {
              if (e.lengthComputable) {
                let p =
                  e.loaded / e.total == 1
                    ? "99"
                    : parseInt((e.loaded / e.total) * 100);
                loading.setText(`上传处理中,请稍等…(${p}%)`);
              }
            },
          })
          .then(async (res) => {
            if (res.data.code == 200) {
              let replaceString = await this.processString(res.data.htmlData);
              this.$emit("turnWord", replaceString);
              loading.setText(`上传处理中,请稍等…(100%)`);
              loading.close();
            }
          })
          .catch((error) => {
            // 捕获错误并处理
            if (error.response) {
              // 服务器返回了响应，但状态码不是 2xx 范围内的
              this.$modal.msgError(error.response.data.msg);
            } else if (error.request) {
              // 请求已经发送了，但没有收到响应
              console.log(error.request, "请求已经发送了，但没有收到响应");
              this.$modal.msgError("node服务器异常");
            } else {
              // 发送请求时发生了一些错误
              console.log("Error", error.message);
              this.$modal.msgError("系统错误");
            }
            loading.close();
          });
      }
      event.value = "";
    },
    readFileAsArrayBuffer(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsArrayBuffer(file);
      });
    },
    showFormula(){
      this.open = true;
    },
    handleClose() {
      this.open = false;
    },
    sureBtn(){
      const kfe = this.$refs.inputIFrameRef.contentWindow.kfe;
      let latex = kfe.execCommand('get.source');
      latex = latex.replace(/\s/g, ''); // 去掉空格

      if (latex === '\\placeholder') {
        this.$modal.msgWarning('请输入公式')
        return;
      }
      let str = `<p><span data-w-e-type="formula" data-w-e-is-void data-w-e-is-inline data-value="${latex}"></span></p>`;
      this.$emit('turnWord',str);
      this.handleClose()
    },
    async insertPdfAsImage(pdfUrl) {
      console.log(pdfUrl, "pdfUrl");
      const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
      const numPages = pdf.numPages;
      let replaceString = "";
      for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
        const page = await pdf.getPage(pageNumber);
        const viewport = page.getViewport({ scale: 1 });
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        await page.render({ canvasContext: context, viewport }).promise;
        const imageData = canvas.toDataURL("image/png");
        let imgBase64 = `<img src="${imageData}" alt="Page ${pageNumber}" />`;
        const base64Data = imgBase64.match(
          /data:image\/[^;]+;base64,([^">]+)/
        )[1];
        let file = base64ToFile(base64Data, "editor_image.png", "image/png");
        let res = await uploadOSS(file);
        replaceString += `<img src="${res[0]}" alt="Page ${pageNumber}" />`;
      }
      return replaceString;
    },

    async processString(editorContent) {
      const imgRegex =
        /<img[^>]+src="data:image\/[^;]+;base64,([^">]+)"[^>]*>/g;

      let processedString = editorContent;

      const imgTags = processedString.match(imgRegex);
      if (!imgTags) {
        return processedString;
      }
      let replaceString = editorContent;
      for (const imgTag of imgTags) {
        const base64Data = imgTag.match(/data:image\/[^;]+;base64,([^">]+)/)[1];
        let file = base64ToFile(base64Data, "editor_image.png", "image/png");
        let res = await uploadOSS(file);
        replaceString = replaceString.replace(
          imgTag,
          `<img src="${res[0]}" />`
        );
      }
      return replaceString;
    },
  },
};
</script>
<style lang="scss" scoped>
.drawer_container{
  width: 100%;
  padding: 0 20px 0 20px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  .drawer_content{
    width: 100%;
    height: calc(100vh - 200px);
    overflow: auto;
  }
  .sign{
    width: 100%;
    font-family: PingFangSC, PingFang SC, sans-serif;
    font-size: 14px;
    font-weight: 400;
    color: #ef820a;
    margin-bottom: 20px;

  }
  .bottom_btns{
    margin-top: 20px;
    width: 100%;
    display: flex;
    justify-content: flex-end;
  }

}
</style>
<style lang="scss">
.wangeditor {
  border: 1px solid #e6e6e6;
  box-sizing: border-box;
}

.w-e-text {
  height: 400px !important;
  overflow: auto !important;
}

.w-e-text-container {
  z-index: 0 !important;
}

.w-e-toolbar {
  z-index: 1 !important;
}
.word_fs {
  width: 18px;
  height: 18px;
  opacity: 0.6;
}
.w-e-menu:hover {
  .word_fs {
    opacity: 1;
  }
}
.w-e-full-screen-editor {
  z-index: 1000 !important;
}
.fullscreen_text {
  height: 100% !important;
}
</style>

